package com.bl.file.util;

import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author yangxiaodong
 * @version 1.0
 * @description: TODO
 * @date 2025/7/2 15:49
 */
@Slf4j
public class ByteBufUploadHelper {
    private final AtomicLong totalWritten = new AtomicLong(0);
    private final long startNano;
    private volatile long lastPrintNano;
    private final String fileName;

    public ByteBufUploadHelper(String fileName) {
        this.fileName = fileName;
        this.startNano = System.nanoTime();
        this.lastPrintNano = this.startNano;
    }

    public String getFileName() {
        return fileName;
    }

    /**
     * 安全写入 ByteBuf 到 FileChannel
     */
    public int writeToChannel(ByteBuf buf, java.nio.channels.WritableByteChannel outChannel) throws Exception {
        int readable = buf.readableBytes();
        ByteBuffer nioBuf = buf.nioBuffer();
        while (nioBuf.hasRemaining()) {
            outChannel.write(nioBuf);
        }
        totalWritten.addAndGet(readable);
        return readable;
    }

    /**
     * 每 N 秒打印上传平均速度
     */
    public void tryLogProgress(int intervalSeconds) {
        long now = System.nanoTime();
        long elapsedMs = (now - lastPrintNano) / 1_000_000;
        if (elapsedMs >= intervalSeconds * 1000L) {
            double totalSec = (now - startNano) / 1_000_000_000.0;
            double mb = totalWritten.get() / 1024.0 / 1024.0;
            double speed = mb / totalSec;
            log.info(String.format("平均上传速度: %.2f MB/s (累计 %.6f MB)", speed, mb));
            lastPrintNano = now;
        }
    }

    public long getTotalBytesWritten() {
        return totalWritten.get();
    }

    public double getAverageSpeedMBps() {
        double totalSec = (System.nanoTime() - startNano) / 1_000_000_000.0;
        return getTotalBytesWritten() / 1024.0 / 1024.0 / totalSec;
    }

    public double getTotalSecond() {
        return (System.nanoTime() - startNano) / 1_000_000_000.0;
    }

}
